
#include "driver/value_table.h"
#include "jxos_public.h"

//event -> attributer -> hardware

#define ATTR_TIME_COUNTER		0
#define ATTR_MODE	            1
#define ATTR_RUN_STATE          2

#define STATE_OFF		0
#define STATE_STAND_BY	1
#define STATE_RUNNING	2
#define STATE_OUTPUT	3

#define output_led_id       0
#define stand_by_led_id     1
#define ir_840_led_id       2
#define red_660_led_id      3

void sy6995_i2c_init(void);
void sy6995_bus_voltage_set_12v(void);
void sy6995_read(void);
void sy6995_charge_out(void);
void sy6995_input_enable(void);

static void ir_output_delay_start(void);
static void ir_output_delay_stop(void);

void light_attribute_changed_handler(uint16_t attribute_id, uint16_t changed_attribute)
{
    uint16_t temp_run_state;
    uint16_t temp_time_counter;
    value_table_get_value(ATTR_RUN_STATE, &temp_run_state);
    value_table_get_value(ATTR_TIME_COUNTER, &temp_time_counter);

    changed_attribute = changed_attribute;

    printf_string("-----------------------\r\n");
    printf_16bit_hex(attribute_id);
    printf_string(" attribute_id\r\n");
    printf_16bit_hex(changed_attribute);
    printf_string(" changed_attribute\r\n");

    printf_16bit_hex(temp_run_state);
    printf_string(" temp_run_state\r\n");
    // printf_16bit_hex(temp_mode);
    // printf_string(" temp_mode\r\n");
    // printf_16bit_hex(temp_time_counter);
    // printf_string(" temp_time_counter\r\n");
    printf_string("-----------------------\r\n");

    switch (temp_run_state){
    case STATE_OFF:
		sy6995_input_enable();
        std_app_led_blink_stop(output_led_id);
        std_app_led_blink_stop(stand_by_led_id);
        std_app_led_blink_stop(ir_840_led_id);
        std_app_led_blink_stop(red_660_led_id);

        std_app_led_blink_off(output_led_id);
        std_app_led_blink_off(stand_by_led_id);
        std_app_led_blink_off(ir_840_led_id);
        std_app_led_blink_off(red_660_led_id);
		ir_output_delay_stop();
        break;

    case STATE_STAND_BY:
        if(attribute_id == ATTR_RUN_STATE){
			sy6995_input_enable();
            std_app_led_blink_on(stand_by_led_id);
            std_app_led_blink_off(ir_840_led_id);
            std_app_led_blink_off(red_660_led_id);
			ir_output_delay_stop();
        }
        break;

    case STATE_RUNNING:
        if(attribute_id == ATTR_RUN_STATE){
			sy6995_bus_voltage_set_12v();
            std_app_led_blink_on(stand_by_led_id);
            std_app_led_blink_off(ir_840_led_id);
            std_app_led_blink_on(red_660_led_id);
			ir_output_delay_start();
        }
		break;

    case STATE_OUTPUT:
        if(attribute_id == ATTR_RUN_STATE){
			sy6995_charge_out();
            std_app_led_blink_on(output_led_id);
        }
		break;
        
    default:
        break;
    }
}

/*********************************************************************/
void pause_handler(void)
{
    uint16_t temp_run_state;
    value_table_get_value(ATTR_RUN_STATE, &temp_run_state);

    if(temp_run_state == STATE_STAND_BY){
        value_table_set_value(ATTR_RUN_STATE, STATE_RUNNING);
    }
    else if(temp_run_state == STATE_RUNNING){
        value_table_set_value(ATTR_RUN_STATE, STATE_STAND_BY);
    }
}

void on_handler(void)
{
    uint16_t temp_run_state;
    value_table_get_value(ATTR_RUN_STATE, &temp_run_state);

    if(temp_run_state == STATE_OFF){
        value_table_set_value(ATTR_RUN_STATE, STATE_STAND_BY);
        value_table_set_value(ATTR_TIME_COUNTER, 10*60);
    }
}

void off_handler(void)
{
    uint16_t temp_run_state;
    value_table_get_value(ATTR_RUN_STATE, &temp_run_state);

    if((temp_run_state == STATE_STAND_BY)
        ||(temp_run_state == STATE_RUNNING)){
        value_table_set_value(ATTR_RUN_STATE, STATE_OFF);
        value_table_set_value(ATTR_TIME_COUNTER, 0);
    }
}

void output_handler(void)
{
    uint16_t temp_run_state;
    value_table_get_value(ATTR_RUN_STATE, &temp_run_state);

    if(temp_run_state == STATE_OFF){
        value_table_set_value(ATTR_RUN_STATE, STATE_OUTPUT);
    }
    else if(temp_run_state == STATE_OUTPUT){
        value_table_set_value(ATTR_RUN_STATE, STATE_OFF);
    }
}

static void timer_tick_handler(void)
{
    uint16_t temp_run_state;
    uint16_t temp_time_counter;
    value_table_get_value(ATTR_RUN_STATE, &temp_run_state);
    value_table_get_value(ATTR_TIME_COUNTER, &temp_time_counter);

    if(temp_run_state == STATE_RUNNING){
        temp_time_counter--;
        value_table_set_value(ATTR_TIME_COUNTER, temp_time_counter);
        if(temp_time_counter == 0){
            value_table_set_value(ATTR_RUN_STATE, STATE_OFF);
        }
    }
}

/*********************************************************************/
static swtime_type event_tick_swt;
static swtime_type ir_output_delay_swt;
static void event_tick_task(void)
{
    if(sys_svc_software_timer_check_overtime(event_tick_swt)){
        timer_tick_handler();
		//sy6995_read();
    }

    if(sys_svc_software_timer_check_overtime(ir_output_delay_swt)){
		sys_svc_software_timer_stop(ir_output_delay_swt);
		std_app_led_blink_on(ir_840_led_id);
    }
}

void event_tick_task_init(void)
{
    value_table_init();
    value_table_set_value(ATTR_RUN_STATE, STATE_OFF);
    value_table_set_value(ATTR_TIME_COUNTER, 0);

    jxos_task_create(event_tick_task, "e", 0);

    event_tick_swt = sys_svc_software_timer_new();
    sys_svc_software_timer_set_time(event_tick_swt, 1000);    //1sec
    sys_svc_software_timer_restart(event_tick_swt);

	ir_output_delay_swt = sys_svc_software_timer_new();

    sy6995_i2c_init();
	sy6995_input_enable();
}

static void ir_output_delay_start(void)
{
	sys_svc_software_timer_set_time(ir_output_delay_swt, 250);
	sys_svc_software_timer_restart(ir_output_delay_swt);
}

static void ir_output_delay_stop(void)
{
	sys_svc_software_timer_stop(ir_output_delay_swt);
    std_app_led_blink_off(ir_840_led_id);
}
